﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Prism.Collections.Generic
{
    [Serializable]
    public class TreeNode<ValueType>
    {
        protected TreeNode()
        {
        }

        public TreeNode(ITreeEnumerating hostTree)
        {
            this.HostTree = hostTree;
            this.Children = new List<TreeNode<ValueType>>();
        }

        public ITreeEnumerating HostTree { get; protected set; }

        private TreeNode<ValueType> parent;
        public virtual TreeNode<ValueType> Parent
        {
            get
            {
                if (this.HostTree.IsEnumerating)
                    throw new InvalidOperationOnEnumeratingException();
                return this.parent;
            }
            set
            {
                if (this.HostTree.IsEnumerating)
                    throw new InvalidOperationOnEnumeratingException();
                this.parent = value;
            }
        }

        private IList<TreeNode<ValueType>> children;
        public virtual IList<TreeNode<ValueType>> Children
        {
            get
            {
                if (this.HostTree.IsEnumerating)
                    throw new InvalidOperationOnEnumeratingException();
                return this.children;
            }
            protected set
            {
                this.children = value;
            }
        }

        private ValueType value;
        public virtual ValueType Value
        {
            get
            {
                if (this.HostTree.IsEnumerating)
                    throw new InvalidOperationOnEnumeratingException();
                return this.value;
            }
            set
            {
                if (this.HostTree.IsEnumerating)
                    throw new InvalidOperationOnEnumeratingException();
                this.value = value;
            }
        }

        public virtual TreeNode<ValueType> DepthPrevious()
        {
            if (this.Parent == null)
                throw new InvalidOperationException("This node's parent is null.");
            else return this.Parent;
        }

        public virtual TreeNode<ValueType> DepthNext()
        {
            if (this.Children.Count != 0)
            {
                return this.Children.First();
            }
            else
            {
                throw new InvalidOperationException("This node has no child.");
            }

        }
    }
}
